#include <stdio.h>
#include <pthread.h>


/*
    任务并行:(Task Parallel)
        使用多个线程处理不同的数据，最后综合起来；
        一般对于多线程的使用是一次创建，重复使用，因为线程和进程的创建和释放都非常的耗费资源
*/

#define THREAD_NUMS 4
/*fibonacci 斐波那契数列的开发，规律是出去第一、第二个数后的数是前两个数的和*/

//递归实现
// n为第几个fibonacci数
int fibonacci_com(int n)
{

    if (n <= 1)
    {
        return n;
    }
    else
    {
        return (fibonacci_com(n-1)+fibonacci_com(n-2));
    }
}

// 非递归实现
int fibonacci_com_no(int n)
{

    if (n <= 1)
    {
        return n;
    }
    else
    {
        int a = 0;
        int b = 1;
        for (int i = 2;i <= n;i++)
        {
            int temp = a+b;

            a = b;

            b = temp;
        }
        return b;
    }
}

/*多线程实现fibonacci*/
// 线程handler函数返回参数的使用，可以返回全局变量和申请堆空间

void* fibonacci_com_func(void *argv)
{
    int n = *((int*)argv);
    int *ret = (int*)malloc(sizeof(int));
    *ret = 0;

    if (n <= 1)
    {
        *ret = n;
    }
    else
    {
        int a = 0;
        int b = 1;
        for (int i = 2;i <= n;i++)
        {
            int temp = a+b;

            a = b;

            b = temp;
        }
        *ret =  b;
    }

    return ret;
}



int main(int argc, char *argv[])
{

    printf("Fibonacci: [ ");
    for (int i = 0;i <= 10;i++)
    {
        printf(" %d ",fibonacci_com_no(i));
    }

    printf(" ] \n");


    pthread_t thread_id[THREAD_NUMS];

    int in = 10;
    int result[THREAD_NUMS] = {0};
    for (int i = 0;i < THREAD_NUMS;i++)
    {
        /*线程属性： 包括调度策略，调度的优先级，线程的分离状态（分离线程：主动结束 和 可汇合线程：等待原有创建线程结束才结束，即pthread_ioin()调用后，该子线程结束），线程ID，线程的继承性，*/
        pthread_create(&thread_id[i],NULL,fibonacci_com_func,&in);
    }

    for (int i = 0;i < THREAD_NUMS;++i)
    {
        void * ret;
        pthread_join(thread_id[i],&ret);
        result[i] = *((int *)ret);

        free(ret);
    }

    int finalResult = 0;
    for (int i = 0; i < THREAD_NUMS; i++) {
        finalResult += result[i];
    }

    printf("The %dth Fibonacci number is: %d\n", in, finalResult);

    return 0;
}